package com.foton.mybatis.excuter;

import com.foton.mybatis.configration.Configration;
import com.foton.mybatis.handler.ParameterHandler;
import com.foton.mybatis.handler.ResultSetHandler;
import com.foton.mybatis.handler.StatementHandler;
import com.foton.mybatis.handler.impl.DefaultParameterHandler;
import com.foton.mybatis.handler.impl.DefaultResultSetHandler;
import com.foton.mybatis.handler.impl.SimpleStatementHandler;
import com.foton.mybatis.model.MappedStatement;
import com.foton.mybatis.util.Constant;

import java.sql.*;
import java.util.List;

/**
 * @Author RenPu
 * @Date 2023/3/29 18:05
 * @Version 1.0
 * @Description:
 **/
public class SimpleExcuter implements Excuter {


    /**
     * 数据库连接对象
     */
    private static Connection connection;


    /**
     * 配置对象
     */
    private Configration conf;

    public SimpleExcuter(Configration configration) {
        this.conf=configration;
    }


    static {
        initConnect();
    }

    private static void initConnect() {
        String diver=Configration.getProperty(Constant.DB_DRIVER_CONF);
        String url=Configration.getProperty(Constant.DB_URL_CONF);
        String username=Configration.getProperty(Constant.DB_USERNAME_CONF);
        String password=Configration.getProperty(Constant.DB_PASSWORD_CONF);
        try {
            //获取数据库驱动
            Class.forName(diver);
            connection=DriverManager.getConnection(url,username,password);
            System.out.println("数据库连接成功=========connect  success===========");
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    /**
     * 获取数据库连接对象
     * @return
     */
    public Connection getConnection(){
        if(null!=connection){
            return connection;
        }else {
            throw new IllegalArgumentException("无法连接数据，请检查配置=====connect  fail =====");
        }
    }


    /**
     * 查询操作方法
     * @param ms
     * @param parameter
     * @param <E>
     * @return
     */
    @Override
    public <E> List<E> doQuery(MappedStatement ms, Object parameter) {

        //获取数据库连接对象
        Connection connection = getConnection();

        //根据sqlId值获取对应的MappedStatement对象
        MappedStatement mappedStatement=conf.getMappedStatement(ms.getSqlId());

        //将MappedStatement对象交由StatementHandler进行实例化
        StatementHandler statementHandler=new SimpleStatementHandler(mappedStatement);


        //通过StatementHandler的prepare方法获取，Connection对象和PreparedStatement对象
        PreparedStatement preparedStatement =statementHandler.prepare(connection);

        //实例化ParameterHandler,将sql中得？占位符参数化
        ParameterHandler parameterHandler=new DefaultParameterHandler(parameter);
        parameterHandler.setParameters(preparedStatement);

        //执行sql获取对应得ResultSet结果集
        ResultSet resultSet = null;
        try {
            resultSet = statementHandler.query(preparedStatement);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        //通过反射机制将结果集和返回类型进行映射封装
        ResultSetHandler resultSetHandler=new DefaultResultSetHandler(mappedStatement);

        return resultSetHandler.handlerResultSets(resultSet);
    }


    /**
     * 修改操作方法
     * @param ms
     * @param paramete
     */
    @Override
    public void doUpdate(MappedStatement ms, Object paramete) {
       try{
           //获取数据库连接对象
           Connection connection = getConnection();

           //根据sqlId值获取对应的MappedStatement对象
           MappedStatement mappedStatement=conf.getMappedStatement(ms.getSqlId());

           //将MappedStatement对象交由StatementHandler进行实例化
           StatementHandler statementHandler=new SimpleStatementHandler(mappedStatement);

           //通过StatementHandler的prepare方法获取，Connection对象和PreparedStatement对象
           PreparedStatement preparedStatement =statementHandler.prepare(connection);

           //实例化ParameterHandler,将sql中得？占位符参数化
           ParameterHandler parameterHandler=new DefaultParameterHandler(paramete);
           parameterHandler.setParameters(preparedStatement);

           //执行sql
           statementHandler.update(preparedStatement);

       }catch (Exception e){
           e.printStackTrace();
       }
    }



}
